package com.hexinfo.dmpro.monitor.service;

import com.alibaba.fastjson.JSONObject;
import com.hexinfo.dmpro.monitor.model.base.MonitorReq;
import com.hexinfo.dmpro.monitor.model.base.MonitorRsp;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author peng
 * @date 2021/9/28 11:18
 */
@Slf4j
public abstract class MonitorBaseService<R, Q> {

    private final String HTTP_GET = "get";

    private final String HTTP_POST = "post";

    private final String CHARSET = "utf-8";

    private final int code = 200;

    @Autowired
    private RestTemplate restTemplate;


    public R execute(Q q) {
        MonitorReq monitorReq = getReqInfo(q);
        MonitorRsp monitorRsp = getInfo(monitorReq);
        R r = null;
        if (isReturned(monitorRsp)) {
            r = parse(monitorRsp);
            saveInfo(r);
        }else{
            r = (R)monitorRsp;
        }
        return r;
    }


    private MonitorRsp getInfo(MonitorReq monitorReq) {
        if (HTTP_GET.equals(monitorReq.getMethod())) {
            return HttpGetExec(monitorReq);
        } else if (HTTP_POST.equals(monitorReq.getMethod())) {
            return HttpGetExec(monitorReq);
        }
        return HttpGetExec(monitorReq);
    }

    private MonitorRsp HttpGetExec(MonitorReq monitorReq) {

        String url = monitorReq.getUrl();
        List<NameValuePair> pairs = getRequestPair(monitorReq.getReqData());
        if (pairs != null && pairs.size()>0) {
            try {
                url += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, CHARSET));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if(monitorReq.getHeader()!=null){
            Map<String, Object> reqHeader = monitorReq.getHeader();
            for(String key : reqHeader.keySet()){
                if(key.equals("Authorization")){
                    headers.set("Authorization",reqHeader.get("Authorization").toString());
                }
            }
        }

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        MonitorRsp monitorRsp = new MonitorRsp();
        monitorRsp.setCenterId(monitorReq.getCenterId());
        monitorRsp.setCenterName(monitorReq.getCenterName());
        monitorRsp.setCmFlag(monitorReq.getCmFlag());
        monitorRsp.setCmName(monitorReq.getCmName());
        monitorRsp.setClusterFlag(monitorReq.getClusterFlag());
        monitorRsp.setClusterName(monitorReq.getClusterName());
        monitorRsp.setMonitorId(monitorReq.getMonitorId());
        monitorRsp.setMonitorName(monitorReq.getMonitorName());
        monitorRsp.setNodeHostName(monitorReq.getNodeHostName());
//        monitorRsp.setCode(200);
//        monitorRsp.setBody("{}");

        //集群高可用，不知道活跃的节点，拼接每个节点循环获取，异常捕获
        try{
//            log.info("Slf4j请求url："+url);
//            logger.info("logger请求url："+url);
            ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, formEntity, String.class);
            monitorRsp.setCode(exchange.getStatusCodeValue());
//            log.info("Slf4j返回报文："+exchange.getBody());
            monitorRsp.setBody(exchange.getBody());
        } catch(Exception e){
            monitorRsp.setCode(MonitorParam.EXCEPTION_CODE);
            monitorRsp.setMessage(e.toString());
            //log.error("调用源生接口获取数据失败 当前请求url 为： " + monitorReq.getUrl());
            //log.error(e.toString());
        }
        return monitorRsp;
    }

    public JSONObject getRequestCmApi(MonitorReq monitorReq) {
        String url = monitorReq.getUrl();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        if(monitorReq.getHeader()!=null){
            Map<String, Object> reqHeader = monitorReq.getHeader();
            for(String key : reqHeader.keySet()){
                if(key.equals("Authorization")){
                    headers.set("Authorization",reqHeader.get("Authorization").toString());
                }
            }
        }
        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        JSONObject obj = null;
        try{
            ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.GET, formEntity, String.class);
            if (code == exchange.getStatusCodeValue()) {
                String body = exchange.getBody();
                obj = JSONObject.parseObject(body);
            }
        } catch(Exception e){
            log.error(e.getMessage(),e);
        }
        return obj;
    }

    private String HttpPostExec(MonitorReq monitorReq) {

        return null;
    }


    protected abstract MonitorReq getReqInfo(Q q);

    protected abstract R parse(MonitorRsp monitorRsp);

    protected abstract void saveInfo(R r);

    protected boolean isReturned(MonitorRsp monitorRsp){
        if(code == monitorRsp.getCode()){
            return true;
        }
        return false;
    }

    private static List<NameValuePair> getRequestPair(Map<String, Object> paramsMap) {
        List<NameValuePair> pairs = new ArrayList<NameValuePair>();
        if (null != paramsMap && !paramsMap.isEmpty()) {
            for (String key : paramsMap.keySet()) {
                pairs.add(new BasicNameValuePair(key, String.valueOf(paramsMap.get(key))));
            }
        }
        return pairs;
    }

}
